# -*- coding: utf-8 -*-

"""" 下载进度条定义
"""

from __future__ import division
import sys
import time
import math

__all__ = ['ProgressBar', 'NoStateProgressBar']

__doc__ = """显示下载进度模块"""


class ProgressBar(object):
    alpha = 2
    count = 1
    n = 100
    length = 50
    piece = length / n

    def __init__(self, total:int, chunksize:int, filename:str, timedelta=.2):
        """初始化进度条类
        
        Arguments:
            total {Number} -- 要下载文件的全部大小
            chunksize {Number} -- 每次下载的分段
            filename {str} -- 文件名
        
        Keyword Arguments:
            timedelta {float} -- 进度条刷新间隔 (default: {.2})
        """

        assert isinstance(total, int), '"total" is a Integer'
        assert isinstance(chunksize, int), '"chunksize" is a Integer'
        assert isinstance(filename, str), '"filename" is a str object'
        self.total = total
        self.chunksize = chunksize
        self.filename = filename
        self.timedelta = timedelta
        self.percent = 0

    def reset(self):
        """重置计数器"""

        self.count = 0
        return self

    def __del__(self):
        del self
    
    def start(self):
        """打印开始下载提示语句"""
        self.info('Start downloading %s ...' % self.filename)
        return self

    def info(self, msg):
        print(msg)

    def close(self):
        """关闭下载状态显示"""
        self.info('finished!')   
        return self.__del__()
    
    def print(self, msg, endpoint='\r'):
        """打印给定字符串信息, 并在结尾加上相应的结束符号"""
        if self.percent is not self.n:
            sys.stdout.write(msg + endpoint)
        else:
            sys.stdout.write(msg + '\n')
        sys.stdout.flush()
        return self

    def update(self):
        """更新进度条状态"""
        percent = int(self.chunksize * self.count / self.total * self.n)  # 计算下载百分比
        length = int(percent * self.piece / self.alpha)  # 计算已经下载的长度
        self.percent = percent
        self.count += 1 
        arrow = '❅' * (length - 2) + '✈'   # 进度条已下载部分的显示状态
        remain = ' ' * (self.length - (len(arrow)+1)*self.alpha) # 进度条未下载部分显示为空格
        self.print('正在下载 [%s] %d%%' % (arrow+remain, percent))
        time.sleep(self.timedelta) # 进度条更新频率


class NoStateProgressBar(object):
    length = 50

    def __init__(self, filename:str):
        """初始化无状态下载进度条
        
        Arguments:
            filename {str} -- 要下载的文件名
        """
        self.filename = filename

    def __del__(self):
        del self

    def close(self):
        self.print('finish', endpoint='\n')
        # print('finished!')
        return self.__del__()

    def start(self):
        print('开始下载 %s' % self.filename)

    def print(self, msg, endpoint='\r'):
        sys.stdout.write(endpoint + msg)
        sys.stdout.flush()

    def update(self, count, block, total):
        """用于urllib.parse.request.urlretrieve
        
        Arguments:
            count -- 已经下载的数据块数量
            block -- 数据块大小
            total -- 远程文件大小
        """
        if total == -1:
            self.print('正在下载 -- 已下载 %dKB' % (count*block/1024))
        else:
            percent = int(count * block / total * 100)
            bloc = int(total / block)
            hesh = '❅' * ((count-1) * int(self.length/bloc)) + '✈'
            spaces = ' ' * (self.length - len(hesh) * 2)
            self.print('正在下载 [%s] %d%%' % (hesh+spaces, percent))
        

class ControlProgress(object):
    """可控制的显示进度条, 用于可中断续传下载"""
    pass


class SingleStepProgressbar(object):
    """单步控制显示进度条, 显示处理进度
    """
    arrow = '❅'
    def __init__(self, total, step, tips):
        self.total = total
        self.step = step
        self.counter = -1
        self.tips = tips
        self.single = math.ceil(total/step)

    def print(self, msg, endpoint=''):
        sys.stdout.write('\r'+ msg + endpoint)

    def start(self):
        print('开始处理...')
        return self.forward()

    def forward(self):
        if self.counter >= self.step:
            return
        self.counter += 1
        if self.step % 2 == 0:
            heshs = self.arrow * (round(self.single * self.counter*0.5) - 1)
        else:
            heshs = self.arrow * round(self.single * self.counter*0.5)
        spaces = ' ' * (self.total - len(heshs) * 2)
        if self.counter == self.step:
            return self.print(self.tips + ' [%s] ' % heshs+' 完成', endpoint='\n')
        return self.print(self.tips + ' [%s] ' % (heshs+spaces))

if __name__=='__main__':
    # p = ProgressBar(100,1,'test.txt',timedelta=0.1)
    # p.start()
    # for i in iter(range(0, 100+1)):
    #     p.update()
    p = SingleStepProgressbar(100,5, '正在处理')
    p.start()
    p.forward()
    p.forward()
    p.forward()
    p.forward()
    p.forward()
    p.forward()
